package handler

import (
	"encoding/json"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"net/http"
	"sync"
	"time"
	"week_exam_2_3/api/request"
	"week_exam_2_3/internal/model"
)

var CliMao map[uint]request.Node = make(map[uint]request.Node)

func Chat(context *gin.Context) {
	var user model.User
	context.Request.ParseForm()
	user_str := context.Request.Form.Get("user")
	json.Unmarshal([]byte(user_str), &user)
	Upgrader := websocket.Upgrader{
		WriteBufferSize: 1024,
		ReadBufferSize:  1024,
	}
	conn, err := Upgrader.Upgrade(context.Writer, context.Request, nil)
	if err != nil {
		context.JSON(http.StatusOK, gin.H{
			"code":    http.StatusBadRequest,
			"message": err.Error(),
		})
		return
	}
	var node = request.Node{
		Conn: conn,
		Data: make(chan []byte, 100),
		Esc:  make(chan bool, 1),
	}
	CliMao[user.ID] = node
	var WG sync.WaitGroup
	WG.Add(2)
	go Read(&node, &WG, user)
	go Write(&node, &WG)
	WG.Wait()
	node.Conn.Close()
	close(node.Data)
	close(node.Esc)
	delete(CliMao, user.ID)
}

func Write(r *request.Node, w *sync.WaitGroup) {
	defer w.Done()
	for data := range r.Data {
		select {
		case <-r.Esc:
			{
				return
			}
		default:

		}
		err := r.Conn.WriteMessage(websocket.TextMessage, data)
		if err != nil {
			r.Esc <- true
			return
		}
	}
}

func Read(r *request.Node, w *sync.WaitGroup, user model.User) {
	defer w.Done()
	for {
		select {
		case <-r.Esc:
			{
				return
			}
		default:

		}
		_, message, err := r.Conn.ReadMessage()
		if err != nil {
			r.Esc <- true
			return
		}
		var chat_read request.ChatReadData
		json.Unmarshal(message, &chat_read)
		var char_write request.ChatWriteData
		char_write.Time = time.Now()
		char_write.Data = chat_read.Data
		char_write.UserId = user.ID
		set, _ := json.Marshal(char_write)
		CliMao[chat_read.SeedId].Data <- set
	}
}
